1. /* slfdvpw2.cpp by K.Tsuru */
  2. // funstion ID = 236 DRADIX, BRADIX
  3. #ifndef SN_H
  4. #include "sn.h"
  5. #endif
  6. /*******************************************************************
  7. SLong and SInteger classes
  8. It divides m by 2^p (< ULONG_MAX/radix) and puts into q,i.e.
  9. q = m/(2^p). It returns the remainder. It is three over times faster
  10. than a statement
  11. q = LsDiv(m, 1uL << p);
  12. ********************************************************************/
  13. long LDivPow2(const SLong& m, SLong& q, uint p){
  14. if(p == 0){ q = m; return 0; }
  15. int mh = (int)m.Head(), mt = (int)m.Tail();
  16. ulong div = (p <= 2u*(uint)BRADIX_BITS) ? (1uL << p) : ULONG_MAX, div1 = div-1uL;
  17. if(div > m.SlOpMaxValue()) q.SetError(q.OUT_OF_RANGE, "LDivPow2", 236);
  18. int ms = m.Sign(236);
  19. if(mh <= 1){ //under two figures, including m = 0
  20. long r;
  21. q = LsDiv(m, div, &r);
  22. return r;
  23. }
  24. //Pay attention to the case &m == &q.
  25. if(&m != &q){
  26. q.valloc(m.Size(), -1);
  27. if(mt) q.figure.clear(0, (uint)mt-1u);
  28. q.figure.clear((uint)mh+1u);
  29. }
  30. ulong rem = 0, u; // rem : remainder
  31. ulong rdx = (ulong)m.Radix();
  32. const fType* mv = m.ReadFigures();
  33. fType* qv = q.figure.Elements();
  34. #ifndef NDEBUG
  35. m.figure(mh);
  36. #endif
  37. for(int i = mh; i >= mt; i--) {
  38. u = (ulong)mv[i]+ rem*rdx;
  39. qv[i] = fType(u >> p);
  40. rem = u & div1;
  41. }
  42. if(rem){
  43. while(mt > 0){
  44. u = rem*rdx;
  45. mt--; qv[mt] = fType(u >> p);
  46. rem = u & div1;
  47. }
  48. }
  49. //It gets figure positions. mh > 0
  50. while(mh && !qv[mh]) mh--; //a few times
  51. q.aHead = (uint)mh;
  52. #ifndef NDEBUG
  53. q.figure(mh); q.figure(mt);
  54. #endif
  55. // 24 0000....0001 / 2 = 12 0000 ... 0000
  56. if(qv[mh]){ // q != 0
  57. while(!qv[mt]) mt++;
  58. q.SetSign(m.Sign());
  59. } else { // q == 0
  60. mt = 0; q.SetSign(0);
  61. }
  62. q.aTail = (uint)mt;
  63. return (long)ms*(long)rem; //The reminder has the same sign as m.
  64. }

slfdvpw2.cpp : last modifiled at 2017/03/13 14:32:00(1,854 bytes)
created at 2017/10/07 10:26:50
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).